package com.ruoyi.ems.controller;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.ems.domain.Order;
import com.ruoyi.ems.domain.Product;
import com.ruoyi.ems.domain.RefundOrder;
import com.ruoyi.ems.domain.Staff;
import com.ruoyi.ems.service.IOrderService;
import com.ruoyi.ems.service.IProductService;
import com.ruoyi.ems.service.IRefundOrderService;
import com.ruoyi.ems.service.IStaffService;
import com.ruoyi.ems.utils.HttpTool;
import com.ruoyi.ems.utils.OrderCodeUtils;
import com.ruoyi.ems.utils.SignatureUtil;
import com.ruoyi.ems.vo.OrderDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 订单Controller
 * 
 * @author sh
 * @date 2023-12-11
 */
@Slf4j
@Anonymous
@RestController
@RequestMapping("/ems/order")
public class OrderController extends BaseController
{
    @Autowired
    private IOrderService orderService;

    @Autowired
    private IStaffService staffService;

    @Autowired
    private StaffController staffController;

    @Autowired
    private IRefundOrderService refundOrderService;

    @Autowired
    private IProductService productService;


//    private static String url ="http://127.0.0.1:8085/api/t-order";
    private static String url ="http://47.110.49.47:8085/api/t-order";

    /**
     * 查询订单列表
     */
//    @PreAuthorize("@ss.hasPermi('ems:order:list')")
    @GetMapping("/list")
    public TableDataInfo list(Order order)
    {
        startPage();
        List<Order> list = orderService.selectOrderList(order);
        return getDataTable(list);
    }

    /**
     * 导出订单列表
     */
//    @PreAuthorize("@ss.hasPermi('ems:order:export')")
    @Log(title = "订单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Order order)
    {
        List<Order> list = orderService.selectOrderList(order);
        ExcelUtil<Order> util = new ExcelUtil<Order>(Order.class);
        util.exportExcel(response, list, "订单数据");
    }

    /**
     * 获取订单详细信息
     */
//    @PreAuthorize("@ss.hasPermi('ems:order:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(orderService.selectOrderById(id));
    }

    /**
     * 新增订单
     */
//    @PreAuthorize("@ss.hasPermi('ems:order:add')")
    @Log(title = "订单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Order order)
    {
        return toAjax(orderService.insertOrder(order));
    }

    /**
     * 修改订单
     */
//    @PreAuthorize("@ss.hasPermi('ems:order:edit')")
    @Log(title = "订单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Order order)
    {
        return toAjax(orderService.updateOrder(order));
    }

    /**
     * 删除订单
     */
//    @PreAuthorize("@ss.hasPermi('ems:order:remove')")
    @Log(title = "订单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(orderService.deleteOrderByIds(ids));
    }

    // 卡劵创建订单
    @Transactional
    @PostMapping("/creatOrder")
    public AjaxResult creatOrder(@RequestBody Map<String , String > map) {
        try {
            String coupons = map.get("type");
            String productName = map.get("productName");
            String stock = map.get("stock");
            String image = map.get("image");
            String staffId = map.get("staffId");
            Staff staff = staffService.selectStaffById(Long.valueOf(staffId));
            Order order = new Order();
            order.setOpenId(Long.valueOf(staffId));
            order.setType(coupons);
            order.setOrderCode(OrderCodeUtils.generateOrderNumber());

            String sellScore = map.get("sellScore");
            if (staff.getScore() < Integer.parseInt(sellScore)){
                return AjaxResult.error("积分不足");
            }
            if (Integer.parseInt(stock) <= 0){
                return AjaxResult.error("库存不足");
            }
            // 说明是卡劵
            String account = map.get("account");
            String code = map.get("code"); // 商品code
            order.setAccount(account);
            order.setProductName(productName);
            order.setProductNum("1");
            order.setProductImg(image);
            order.setTotalPrice(Integer.valueOf(sellScore));
            order.setProductCode(code);
            order.setCallbackCount(10);
            order.setCreatTime(new Date());
            orderService.insertOrder(order);
            staff.setScoreTmp(-Integer.parseInt(sellScore));
            staff.setScoreExplainInfo("下单扣费，订单号：" + order.getOrderCode() + "，积分：" + sellScore);
            staffController.updateStaffScore(staff);
            return submitOrder(order);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error();
        }
    }

    // 卡劵提交订单
    @Transactional
    @PostMapping("/submitOrder")
    public AjaxResult submitOrder(@RequestBody Order order){
        long timeNow = System.currentTimeMillis();
        String urlIp = "http://120.26.223.111:9090/v1/SubmitOrder";

        HashMap<String, String> params = new HashMap<>();
        // 卡劵
        params.put("Service","SubmitOrder");
        params.put("UserId", "test"); //账号配置 test
        params.put("BizType","ECARD");  //类型要换
        params.put("OrderNo", order.getOrderCode()); //订单号
        params.put("ProductId", order.getProductCode()); //商品id
        params.put("AccountVal", order.getAccount());  // 充值目标账号(签名) 充值账号 手机 qq
        params.put("Time",String.valueOf(timeNow));//时间戳
        String sign = SignatureUtil.generateSign(params, "a367b552cfe347cc88e883158c0f7482"); // 暂无
        params.put("Sign",sign);//签名
        // 查询并修改库存
        String productCode = order.getProductCode();
        Product product = productService.selectProductByCode(productCode);
        if (product.getStock() <= 0){
            order.setOrderStatus("FAILED");
            // 创建退款单
            creatRefundOrder(order);
            orderService.updateOrder(order);
            return AjaxResult.error("下单失败，库存不足");
        }
        product.setStock(product.getStock() - 1);
        productService.updateProduct(product);
        //再查一次积分
        Staff staff = staffService.selectStaffById(order.getOpenId());
        if (staff.getScore() < order.getTotalPrice()){
            order.setOrderStatus("FAILED");
            // 创建退款单
            creatRefundOrder(order);
            orderService.updateOrder(order);
            return AjaxResult.error("下单失败，积分不足");
        }
        // 发请求
        String res = HttpTool.sendPost33(urlIp, params);
        //拿到响应数据
        JSONObject objectRes = JSONObject.parseObject(res);
        String code = String.valueOf(objectRes.getString("code"));
        String msg = objectRes.getString("msg");
        // 0 支付成功，修改订单状态
        if ("0".equals(code)){
            // WAIT_FOR 充值中
            order.setOrderStatus("WAIT_FOR");
            orderService.updateOrder(order);
            // 响应成功
            return AjaxResult.success("下单成功");
        }
        log.info("提单返回状态："+code+msg);
        // 下单失败，修改订单状态为失败
        order.setOrderStatus("FAILED");
        // 创建退款单
        creatRefundOrder(order);
        orderService.updateOrder(order);
        return AjaxResult.error("下单失败");
    }

    // 卡劵 接收回调
    @Transactional
    @PostMapping("/receiveCallback")
    public JSONObject receiveCallback(@RequestBody Map<String, String> map){
        log.info("接收卡劵回调，参数：{}", map);
        String userId = map.get("UserId");
        String bizType = map.get("BizType");
        String orderNo = map.get("OrderNo");
        String accountVal = map.get("AccountVal");
        String orderStatus = map.get("OrderStatus");
        String productData = map.get("ProductData");
        String sign = map.get("Sign");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 0);
        // 验证签名
        // 查询自己这边的订单详情
        Order order = orderService.selectOrderByCode(orderNo);
        if ("FAILED".equals(order.getOrderStatus()) || "SUCCESS".equals(order.getOrderStatus())){
            return jsonObject;
        }
        order.setOrderInfo(productData);
        order.setOrderStatus(orderStatus);
        // 订单失败，创建退款单
        if ("FAILED".equals(orderStatus)){
            creatRefundOrder(order);
        }
        orderService.updateOrder(order);

        return jsonObject;
    }

    // 本地生活创建订单
    @Transactional
    @PostMapping("/creatOrderLocalLife")
    public AjaxResult creatOrderLocalLife(@RequestBody OrderDto orderDto) {
        try {
            String type = orderDto.getType();
            Integer sellScore = orderDto.getSellScore();
            Long staffId = orderDto.getStaffId();
            String account = orderDto.getAccount();
            String productId = orderDto.getProductId();
            String productName = orderDto.getProductName();
            String num = orderDto.getNum();
            String skuName = orderDto.getSkuName();
            String image = orderDto.getImage();
            Boolean showImg = orderDto.getShowImg();

            Staff staff = staffService.selectStaffById(staffId);
            Order order = new Order();

            order.setOpenId(staffId);
            order.setType(type);
            order.setProductImg(image);
            order.setProductName(productName);
            order.setProductNum(num);
            order.setProductSku(skuName);
            order.setShowImg(showImg);
            // 创建订单号
            order.setOrderCode(OrderCodeUtils.generateOrderNumber());

            if (staff.getScore() < sellScore){
                return AjaxResult.error("积分不足");
            }
            order.setTotalPrice(sellScore);
            order.setProductCode(productId);
            order.setAccount(account);
            order.setCreatTime(new Date());
            order.setCallbackCount(10);
            orderService.insertOrder(order);
            staff.setScoreTmp(-sellScore);
            staff.setScoreExplainInfo("下单扣费，订单号：" + order.getOrderCode() + "，积分：" + sellScore);
            staffController.updateStaffScore(staff);
            return submitOrderLocalLife(order, orderDto);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("下单失败");
        }
    }
    // 本地生活提交订单
    @Transactional
    @PostMapping("/submitOrderLocalLife")
    public AjaxResult submitOrderLocalLife(@RequestBody Order order, OrderDto orderDto){
        long timeNow = System.currentTimeMillis();
        String urlIp = url + "/createOrder";

        // 发请求
        String res = HttpTool.sendPost44(urlIp, orderDto);
        //拿到响应数据
        JSONObject objectRes = JSONObject.parseObject(res);
        String code = String.valueOf(objectRes.getString("code"));
        String message = objectRes.getString("message");
        // 返回回来的本地生活的订单编号
        String orderNumber = objectRes.getString("data");
        // 0 支付成功，修改订单状态
        if ("200".equals(code)){

            order.setUpstreamOrderNumber(orderNumber);

            String s = subToLocalLife(orderNumber);
            if ("FAILED".equals(s)){
                // 下单失败，修改订单状态为失败
                order.setOrderStatus("FAILED");
                // 创建退款单
                creatRefundOrder(order);
                orderService.updateOrder(order);
                return AjaxResult.error("下单失败");
            } else {
                order.setOrderStatus("WAIT_FOR");
                orderService.updateOrder(order);
                return AjaxResult.success("下单成功");
            }
        }
        log.info("提单返回状态："+code+message);
        // 下单失败，修改订单状态为失败
        order.setOrderStatus("FAILED");
        order.setErrMsg(message);
        // 创建退款单
        creatRefundOrder(order);
        orderService.updateOrder(order);
        return AjaxResult.error(message);
    }

    /**
     * 提交到本地生活的提交订单接口
     * @param orderNum
     * @return 返回订单状态
     */
    public String subToLocalLife(String orderNum){
        String urlIp = url + "/orkSubmitOrder";
        // 返回订单状态
        String orderStatus = HttpTool.sendPostStr(urlIp, orderNum);
        return orderStatus;
    }

    /**
     * 创建退款单
     * @param order
     */
    @Transactional
    public void creatRefundOrder(Order order) {
        String orderCode = order.getOrderCode();
        RefundOrder refundOrderTmp = refundOrderService.selectRefundOrderByOrderCode(orderCode);
        if (refundOrderTmp != null){
            return;
        }
        // 只要订单是失败状态，就创建退款单
        RefundOrder refundOrder = new RefundOrder();
        refundOrder.setRefundNo(OrderCodeUtils.generateOrderNumber());
        refundOrder.setTradeNo(order.getOrderCode());
        refundOrder.setRefundAmount(order.getTotalPrice());
        refundOrder.setCreationTime(new Date());
        refundOrder.setType(order.getType());
        refundOrder.setStatus("PROCESSING");
        refundOrderService.insertRefundOrder(refundOrder);
    }

    /**
     * 查询用户订单
     * @param map
     * @return
     */
    @PostMapping("/getUserOrder")
    public TableDataInfo getUserOrder(@RequestBody Map<String, String > map){

        try {
            String state = map.get("state");
            String staffId = map.get("staffId");
            if ("ALL".equals(state)){
                state = null;
            } else if ("OTHER".equals(state)){
                state = "WAIT_FOR";
            }
//            String state = orderQuery.getState();
//            String token = orderQuery.getToken();
//            Map<String, String> decrypt = DESUtil.decrypt(token, DESKey);
//            if(decrypt == null){
//                return JSONResult.error(ErrorCode.LOGOUT);
//            }
//            // 获取用户的 admin_id
//            String openId = decrypt.get("openId");
//            String openId = "olWgMuAKQjd9guSnq4tsVVzgzLOU";
            List<Order> orderList = orderService.selectByStaffIdAndStatus(Long.valueOf(staffId), state);

            orderList.sort(Comparator.comparing(Order::getCreatTime).reversed());

            return getDataTable(orderList);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
